package com.qiangesoft.voice2text.service;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

/**
 * 文字转语音
 * jdk bin文件中需要导入jacob-1.17-M2-x64.dll
 *
 * @author qiangesoft
 * @date 2024-04-12
 */
@Service
@ComponentScan
public class TextToSpeechFileService {

    @Value("${filePath:}")
    private String path;

    /**
     * 输入文本内容，生成文件地址
     *
     * @param text
     * @return
     */
    public HashMap<String, String> audioFile(String text) {
        HashMap<String, String> map = new HashMap<>();
        try {
            // 构建音频格式
            Dispatch spAudioFormat = new ActiveXComponent("Sapi.SpAudioFormat").getObject();
            // 音频文件输出流
            Dispatch spFileStream = new ActiveXComponent("Sapi.SpFileStream").getObject();
            // 构建音频对象
            Dispatch spVoice = new ActiveXComponent("Sapi.SpVoice").getObject();

            // 设置spAudioFormat音频流格式类型22
            Dispatch.put(spAudioFormat, "Type", new Variant(22));
            // 设置spFileStream文件输出流的音频格式
            Dispatch.putRef(spFileStream, "Format", spAudioFormat);

            // 随机uuid
            String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
            String filePath = path + uuid + ".wav";

            // 设置spFileStream文件输出流参数地址等
            Dispatch.call(spFileStream, "Open", new Variant(filePath), new Variant(3), new Variant(true));
            // 设置spVoice声音对象的音频输出流为输出文件对象
            Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
            // 设置spVoice声音对象的音量大小100
            Dispatch.put(spVoice, "Volume", new Variant(100));
            // 设置spVoice声音对象的速度 0为正常速度，范围【..-2 -1 0 1 2..】
            Dispatch.put(spVoice, "Rate", new Variant(0));
            // 设置spVoice声音对象中的文本内容
            Dispatch.call(spVoice, "Speak", new Variant(text));
            // 关闭spFileStream输出文件
            Dispatch.call(spFileStream, "Close");

            // 释放资源
            spVoice.safeRelease();
            spAudioFormat.safeRelease();
            spFileStream.safeRelease();

            map.put("code", "1");
            map.put("name", uuid + ".wav");
            map.put("format", "wav");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            map.put("date", sdf.format(new Date()));
        } catch (Exception e) {
            System.out.println(e.getMessage());
            map.put("code", "0");
        }
        return map;
    }

    /**
     * 下载文件
     *
     * @param fileName
     * @param response
     */
    public void down(String fileName, HttpServletResponse response) {
        try {
            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/octet-stream");
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(), "utf-8"));
            InputStream in = new FileInputStream(path + fileName);
            int len;
            byte[] buffer = new byte[1024];
            OutputStream out = response.getOutputStream();
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            in.close();
        } catch (Exception e) {
            System.out.println("文件下载失败");
            e.printStackTrace();
        }
    }

}